
/*
  $Id$
*/

#include "StdAfx.h"

#include "CIDIASymb2Str.h"


#include "CIDIASymb2Str.inc"

//
// CInit_CIDIASymb2Str static members
//
map<DWORD,_tstring> *CInit_CIDIASymb2Str::pMap[]=
{
    &CIDIASymb2Str::mapBasicType,
    &CIDIASymb2Str::mapCV_access_e,
    &CIDIASymb2Str::mapCV_call_e,
    &CIDIASymb2Str::mapCV_CFL_LANG,
    &CIDIASymb2Str::mapCV_CPU_TYPE_e,
    &CIDIASymb2Str::mapCV_HREG_e,
    &CIDIASymb2Str::mapDataKind,
    &CIDIASymb2Str::mapLocationType,
    &CIDIASymb2Str::mapNameSearchOptions,
    &CIDIASymb2Str::mapSymTagEnum,
    &CIDIASymb2Str::mapTHUNK_ORDINAL,
    &CIDIASymb2Str::mapUdtKind,
};

pair<DWORD,_tstring> *CInit_CIDIASymb2Str::pPairs[]=
{
    &CInit_CIDIASymb2Str::pairBasicType[0],
    &CInit_CIDIASymb2Str::pairCV_access_e[0],
    &CInit_CIDIASymb2Str::pairCV_call_e[0],
    &CInit_CIDIASymb2Str::pairCV_CFL_LANG[0],
    &CInit_CIDIASymb2Str::pairCV_CPU_TYPE_e[0],
    &CInit_CIDIASymb2Str::pairCV_HREG_e[0],
    &CInit_CIDIASymb2Str::pairDataKind[0],
    &CInit_CIDIASymb2Str::pairLocationType[0],
    &CInit_CIDIASymb2Str::pairNameSearchOptions[0],
    &CInit_CIDIASymb2Str::pairSymTagEnum[0],
    &CInit_CIDIASymb2Str::pairTHUNK_ORDINAL[0],
    &CInit_CIDIASymb2Str::pairUdtKind[0],
};

//
// CIDIASymb2Str static members
//
map<DWORD,_tstring> CIDIASymb2Str::mapBasicType;
map<DWORD,_tstring> CIDIASymb2Str::mapCV_access_e;
map<DWORD,_tstring> CIDIASymb2Str::mapCV_call_e;
map<DWORD,_tstring> CIDIASymb2Str::mapCV_CFL_LANG;
map<DWORD,_tstring> CIDIASymb2Str::mapCV_CPU_TYPE_e;
map<DWORD,_tstring> CIDIASymb2Str::mapCV_HREG_e;
map<DWORD,_tstring> CIDIASymb2Str::mapDataKind;
map<DWORD,_tstring> CIDIASymb2Str::mapLocationType;
map<DWORD,_tstring> CIDIASymb2Str::mapNameSearchOptions;
map<DWORD,_tstring> CIDIASymb2Str::mapSymTagEnum;
map<DWORD,_tstring> CIDIASymb2Str::mapTHUNK_ORDINAL;
map<DWORD,_tstring> CIDIASymb2Str::mapUdtKind;

map<_tstring, CIDIASymb2Str::DIASymb_mf> CIDIASymb2Str::m_mapPropName2Fun;


//
// declare a instance of CInit_CIDIASymb2Str will automaticly init CIDIASymb2Str
// note this variable should declare after CIDIASymb2Str's static member declare
CInit_CIDIASymb2Str  g_cInitCIDIASymb2Str;	


DWORD CIDIASymb2Str::GetPropertyNum()
{
	return sizeof(m_vcSProperty)/sizeof(m_vcSProperty[0]);
}


_tstring CIDIASymb2Str::GetBOOL(HRESULT (STDMETHODCALLTYPE IDiaSymbol::*mpf)(BOOL*))
{
	_tstring cstrRet;
	BOOL f;
	if(SUCCEEDED((m_pSymbol->*mpf)(&f)))
	{
		(FALSE==f)?cstrRet=_T("false"):cstrRet=_T("true");
	}
	return cstrRet;
}

_tstring CIDIASymb2Str::GetBSTR(HRESULT (STDMETHODCALLTYPE IDiaSymbol::*mpf)(BSTR*))
{
	_tstring strRet;
	_bstr_t bstr;
	if(SUCCEEDED((m_pSymbol->*mpf)(&bstr.GetBSTR())))
	{
		strRet=(TCHAR*)bstr;
	}
	return strRet;
}

_tstring CIDIASymb2Str::GetEnumName(HRESULT (STDMETHODCALLTYPE IDiaSymbol::*mpf)(DWORD*), map<DWORD,_tstring>* pMap)
{
	map<DWORD,_tstring>::iterator it;
	DWORD dw;
	if(SUCCEEDED((m_pSymbol->*mpf)(&dw)))
	{
		it=pMap->find(dw);
		if(it==pMap->end())
		{
			TRACE(_T("Unsport enum id:%d\r\n"), dw);
		}
	}
	return it->second;
}

_tstring CIDIASymb2Str::GetVARIANT(HRESULT (STDMETHODCALLTYPE IDiaSymbol::*mpf)(VARIANT*))
{
	_tstringstream ss;
	VARIANT  va;
	if(SUCCEEDED((m_pSymbol->*mpf)(&va)))
	{
		switch( va.vt )
		{
			//*    LONGLONG       VT_I8
		case VT_I8:
                ss<<_T("VT_I8")<<va.llVal;
			break;
			//*    LONG           VT_I4
		case VT_I4:
                ss<<_T("VT_I4")<<va.lVal;
			break;
			//*    BYTE           VT_UI1
		case VT_UI1:
                ss<<_T("VT_UI1")<<va.bVal;
			break;
			//*    SHORT          VT_I2
		case VT_I2:
                ss<<_T("VT_I2")<<va.iVal;
			break;
			//*    CHAR           VT_I1
		case VT_I1:
                ss<<_T("VT_I1")<<va.cVal;
			break;
			//*    USHORT         VT_UI2
		case VT_UI2:
                ss<<_T("VT_UI2")<<va.uiVal;
			break;
			//*    ULONG          VT_UI4
		case VT_UI4:
                ss<<_T("VT_UI4")<<va.ulVal;
			break;
			//*    ULONGLONG      VT_UI8
		case VT_UI8:
                ss<<_T("VT_UI8")<<va.ullVal;
			break;
			//*    INT            VT_INT
		case VT_INT:
                ss<<_T("VT_INT")<<va.intVal;
			break;
			//*    UINT           VT_UINT
		case VT_UINT:
                ss<<_T("VT_UINT")<<va.uintVal;
			break;
		default:
                ss<<_T("<Not implemented>");
			break;
		}
	}

	return ss.str();
}


CInit_CIDIASymb2Str::CInit_CIDIASymb2Str()
{
	static BOOL s_fInit=FALSE;	// prevent multyinit
	if(FALSE==s_fInit)
	{
		// init emun maps
		for(DWORD i=0; i<sizeof(pMap)/sizeof(pMap[0]); i++)
		{
			for(DWORD j=0; PAIR_END!=pPairs[i][j].second; j++)
			{
				pMap[i]->insert(pPairs[i][j]);
			}
		}

		// init property name to function map
		for(DWORD i=0; i<sizeof(CIDIASymb2Str::m_pmfS)/sizeof(CIDIASymb2Str::m_pmfS[0]); i++)
		{
			CIDIASymb2Str::m_mapPropName2Fun.insert(pair<_tstring, CIDIASymb2Str::DIASymb_mf>(CIDIASymb2Str::m_vcSProperty[i], CIDIASymb2Str::m_pmfS[i]));
		}

		s_fInit=TRUE;
	}
};


